// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2019 Intel Corporation

package cnca

// SubscribedEvent : The possible value is CHANGE_OF_DNAI - the AF requests to
// be notified when the UP path changes for the PDU isession.
type SubscribedEvent string

// Link is a string identifying the referenced resource URI
// URI string formatted accordingding to IETF RFC 3986
type Link string

// SupportedFeatures string used to indicate the features supported by
// an API that is used (subclause 6.6 in 3GPP TS 29.500).
// The string shall contain a bitmask indicating supported features in
// hexadecimal representation.
// Each character in the string shall take a value of "0" to "9" or "A" to "F"
// and shall represent the support of 4 features as described in table 5.2.2-3.
// The most significant character representing the highest-numbered features
// shall appear first in the string,
// and the character representing features 1 to 4 shall appear last
// in the string.
// The list of features and their numbering (starting with 1)
// are defined separately for each API.
// Possible features for traffic influencing are
// Notification_websocket( takes vlue of 1) and
// Notification_test_event(takes value of 2)
// pattern: '^[A-Fa-f0-9]*$'
type SupportedFeatures string

// GPSI type
type GPSI string

// SrcUEIPv4Addr type
type SrcUEIPv4Addr string

// SrcUEIPv6Prefix type
type SrcUEIPv6Prefix string

// TgtUEIPv4Addr type
type TgtUEIPv4Addr string

// TgtUEIPv6Prefix type
type TgtUEIPv6Prefix string

// UEMac type
type UEMac string

// MacAddr type
type MacAddr string

// IPv4Addr type
type IPv4Addr string

// IPv6Addr type
type IPv6Addr string

// DNAI type
type DNAI string

// List of SubscribedEvent
const (
	//UP_PATH_CHANGE SubscribedEvent = "UP_PATH_CHANGE" >> causing lint error
	UPPathChange SubscribedEvent = "UP_PATH_CHANGE"
)

// DNAIChangeType type
type DNAIChangeType string

// List of DnaiChangeType
const (
	Early     DNAIChangeType = "EARLY"
	EarlyLate DNAIChangeType = "EARLY_LATE"
	Late      DNAIChangeType = "LATE"
)

// TrafficInfluSub is Traffic Influence Subscription structure
type TrafficInfluSub struct {
	// Identifies a service on behalf of which the AF is issuing the request.
	AFServiceID string `json:"afServiceId,omitempty"`
	// Identifies an application.
	AFAppID string `json:"afAppId,omitempty"`
	// Identifies an NEF Northbound interface transaction, generated by the AF.
	AFTransID string `json:"afTransId,omitempty"`
	// Identifies data network name
	DNN string `json:"dnn,omitempty"`
	// Network slice identifier
	SNSSAI SNSSAI `json:"snssai,omitempty"` //p
	// string containing a local identifier followed by \"@\" and
	// a domain identifier.
	// Both the local identifier and the domain identifier shall be encoded as
	// strings that do not contain any \"@\" characters.
	// See Clauses 4.6.2 and 4.6.3 of 3GPP TS 23.682 for more information.
	ExternalGroupID string `json:"externalGroupId,omitempty"`
	// Identifies the requirement to be notified of the event(s).
	SubscribedEvents []SubscribedEvent `json:"subscribedEvents,omitempty"`
	//Generic Public Servie Identifiers asssociated wit the UE
	GPSI GPSI `json:"gpsi,omitempty"`
	// string identifying a Ipv4 address formatted in the \"dotted decimal\"
	//notation as defined in IETF RFC 1166.
	IPv4Addr IPv4Addr `json:"ipv4Addr,omitempty"`
	// string identifying a Ipv6 address formatted according to clause 4
	// in IETF RFC 5952.
	IPv6Addr IPv6Addr `json:"ipv6Addr,omitempty"`
	// string identifying mac address of UE
	MacAddr MacAddr `json:"macAddr,omitempty"`
	// Identifies the type of notification regarding UP path management event.
	// Possible values are:
	// EARLY - early notification of UP path reconfiguration.
	// EARLY_LATE - early and late notification of UP path reconfiguration.
	// This value shall only be present in the subscription to the
	// DNAI change event.
	// LATE - late notification of UP path reconfiguration.
	DNAIChgType DNAIChangeType `json:"dnaiChgType,omitempty"`
	// URL where notifications shall be sent
	NotificationDestination Link `json:"notificationDestination,omitempty"`
	// URL of created subscription resource
	Self Link `json:"self,omitempty"`
	// Identifies IP packet filters.
	TrafficFilters []FlowInfo `json:"trafficFilters,omitempty"`
	// Identifies Ethernet packet filters.
	EthTrafficFilters []EthFlowDescription `json:"ethTrafficFilters,omitempty"`
	// Identifies the N6 traffic routing requirement.
	TrafficRoutes []RouteToLocation `json:"trafficRoutes,omitempty"`
	// Settings for temporary validity of the subscription
	TempValidities []TemporalValidity `json:"tempValidities,omitempty"`
	// Identifies a geographic zone that the AF request applies only to the
	// traffic of UE(s) located in this specific zone.
	ValidGeoZoneIDs []string `json:"validGeoZoneIds,omitempty"`
	// String identifying supported features per Traffic Influence service
	SuppFeat SupportedFeatures `json:"suppFeat,omitempty"`
	// Configuration used for sending notifications though web sockets
	WebsockNotifConfig WebsockNotifConfig `json:"websockNotifConfig,omitempty"`
	// Set to true by the AF to request the NEF to send a test notification.
	//Set to false or omitted otherwise.
	RequestTestNotification bool `json:"requestTestNotification,omitempty"`
	// Identifies whether an application can be relocated once a location of
	// the application has been selected.
	AppReloInd bool `json:"appReloInd,omitempty"`
	// Identifies whether the AF request applies to any UE.
	AnyUEInd bool `json:"anyUeInd,omitempty"`
}

// TrafficInfluSubPatch Traffic Influence Subscription Patch structure
type TrafficInfluSubPatch struct {
	// Identifies IP packet filters.
	TrafficFilters []FlowInfo `json:"trafficFilters,omitempty"`
	// Identifies whether an application can be relocated once a location of
	// the application has been selected.
	AppReloInd bool `json:"appReloInd,omitempty"`
	// Identifies Ethernet packet filters.
	EthTrafficFilters []EthFlowDescription `json:"ethTrafficFilters,omitempty"`
	// Identifies the N6 traffic routing requirement.
	TrafficRoutes []RouteToLocation `json:"trafficRoutes,omitempty"`
	// Settings for temporary validity of the subscription
	TempValidities []TemporalValidity `json:"tempValidities,omitempty"`
	// Identifies a geographic zone that the AF request applies only to the
	// traffic of UE(s) located in this specific zone.
	ValidGeoZoneIDs []string `json:"validGeoZoneIds,omitempty"`
}

// TemporalValidity Indicates the time interval(s) during which the AF request
// is to be applied
type TemporalValidity struct {
	// string with format \"date-time\" as defined in OpenAPI.
	StartTime string `json:"startTime,omitempty"`
	// string with format \"date-time\" as defined in OpenAPI.
	StopTime string `json:"stopTime,omitempty"`
}

// EthFlowDescription Identifies an Ethernet flow
type EthFlowDescription struct {
	DestMacAddr string `json:"destMacAddr,omitempty"`
	//EtherType number
	EthType string `json:"ethType"`
	// Defines a packet filter of an IP flow.
	FDesc string `json:"fDesc,omitempty"`
	// Possible values are DOWNLINK - The corresponding filter applies for
	// traffic to the UE.
	// UPLINK - The corresponding filter applies for traffic from the UE.
	// BIDIRECTIONAL The corresponding filter applies for traffic both to and
	// from the UE.
	// UNSPECIFIED - The corresponding filter applies for traffic to the UE
	// (downlink), but has no specific direction declared.
	// The service data flow detection shall apply the filter for uplink traffic
	// as if the filter was bidirectional.
	FDir string `json:"fDir,omitempty"`
	// Source mac address
	SourceMacAddr string `json:"sourceMacAddr,omitempty"`
	// Vlan tags
	VLANTags []string `json:"vlanTags,omitempty"`
}

// WebsockNotifConfig Websocket noticcation configuration
type WebsockNotifConfig struct {
	// string formatted according to IETF RFC 3986 identifying a
	// referenced resource.
	WebsocketURI string `json:"websocketUri,omitempty"`
	// Set by the AF to indicate that the Websocket delivery is requested.
	RequestWebsocketURI bool `json:"requestWebsocketUri,omitempty"`
}

// SNSSAI Network slice identifier
type SNSSAI struct {
	SST int32  `json:"sst"`
	SD  string `json:"sd,omitempty"`
}

// RouteToLocation Route to location structure
type RouteToLocation struct {
	// Data network access identifier
	DNAI DNAI `json:"dnai"`
	// Dnai route profile identifier
	RouteProfID string `json:"routeProfId,omitempty"`
	// Additional route information about the route to Dnai
	RouteInfo RouteInformation `json:"routeInfo,omitempty"`
}

// RouteInformation Route information struct
type RouteInformation struct {
	// string identifying a Ipv4 address formatted in the \"dotted decimal\"
	// notation as defined in IETF RFC 1166.
	IPv4Addr IPv4Addr `json:"ipv4Addr,omitempty"`
	// string identifying a Ipv6 address formatted according to clause 4 in
	// IETF RFC 5952.
	// The mixed Ipv4 Ipv6 notation according to clause 5 of IETF RFC 5952 shall
	// not be used.
	IPv6Addr IPv6Addr `json:"ipv6Addr,omitempty"`
	// Port number
	PortNumber int32 `json:"portNumber"`
}

// ProblemDetails Problem details struct
type ProblemDetails struct {
	// problem type
	Type Link `json:"type,omitempty"`
	// A short, human-readable summary of the problem type.
	// It should not change from occurrence to occurrence of the problem.
	Title string `json:"title,omitempty"`
	// A human-readable explanation specific to this occurrence of the problem.
	Detail string `json:"detail,omitempty"`
	// URL to problem instance
	Instance Link `json:"instance,omitempty"`
	// A machine-readable application error cause specific to this occurrence
	// of the problem.
	// This IE should be present and provide application-related error
	// information, if available.
	Cause string `json:"cause,omitempty"`
	// Description of invalid parameters, for a request rejected due to
	// invalid parameters.
	InvalidParams []InvalidParam `json:"invalidParams,omitempty"`
	// The HTTP status code for this occurrence of the problem.
	Status int `json:"status,omitempty"`
}

// InvalidParam Invalid Parameters struct
type InvalidParam struct {
	// Attribute''s name encoded as a JSON Pointer, or header''s name.
	Param string `json:"param"`
	// A human-readable reason, e.g. \"must be a positive integer\".
	Reason string `json:"reason,omitempty"`
}

// FlowInfo Flow information struct
type FlowInfo struct {
	// Indicates the packet filters of the IP flow. Refer to subclause 5.3.8 of
	//3GPP TS 29.214 for encoding.
	// It shall contain UL and/or DL IP flow description.
	FlowDescriptions []string `json:"flowDescriptions,omitempty"`
	// Indicates the IP flow.
	FlowID int32 `json:"flowId"`
}

// EventNotification structure
type EventNotification struct {
	// AfTransID
	AFTransID string `json:"afTransId,omitempty"`
	// DnaiChgType
	DNAIChgType DNAIChangeType `json:"dnaiChgType,omitempty"`
	// SourceTrafficRoute
	SourceTrafficRoute RouteToLocation `json:"sourceTrafficRoute,omitempty"`
	// SubscribedEvent
	SubscribedEvent SubscribedEvent `json:"subscribedEvent,omitempty"`
	// TargetTrafficRoute
	TargetTrafficRoute RouteToLocation `json:"targetTrafficRoute,omitempty"`
	// Gpsi
	GPSI string `json:"gpsi,omitempty"`
	// SrcUeIpv4Addr
	SrcUEIPv4Addr SrcUEIPv4Addr `json:"srcUeIpv4Addr,omitempty"`
	// SrcUeIpv6Prefix
	SrcUEIPv6Prefix SrcUEIPv6Prefix `json:"srcUeIpv6Prefix,omitempty"`
	// TgtUeIpv4Addr
	TgtUEIP4Addr TgtUEIPv4Addr `json:"tgtUeIpv4Addr,omitempty"`
	// TgtUeIpv6Prefix
	TgtUEIPv6Prefix TgtUEIPv6Prefix `json:"tgtUeIpv6Prefix,omitempty"`
	// UeMac
	UEMac UEMac `json:"ueMac,omitempty"`
}

// DurationSec is unsigned integer identifying a period of time in units of
// seconds.
type DurationSec uint64

// DurationSecRm is unsigned integer identifying a period of time in units of
// seconds with "nullable=true" property.
type DurationSecRm DurationSec

// DurationSecRo is unsigned integer identifying a period of time in units of
// seconds with "readOnly=true" property.
type DurationSecRo DurationSec

// Pfd is the structure of Packet Flow Description for an external Application
// Identifier
type Pfd struct {
	// Identifies a PDF of an application identifier.
	PfdID string `json:"pfdID"`
	// Represents a 3-tuple with protocol, server ip and server port for UL/DL
	// application traffic. The content of the string has the same encoding as
	// the IPFilterRule AVP value as defined in IETFÂ RFCÂ 6733.
	FlowDescriptions []string `json:"flowDescriptions,omitempty"`
	// Indicates a URL or a regular expression which is used to match the
	// significant parts of the URL.
	Urls []string `json:"urls,omitempty"`
	// Indicates an FQDN or a regular expression as a domain name matching
	// criteria.
	DomainNames []string `json:"domainNames,omitempty"`
}

// PfdData is the type that represents a PFD request to add, update or remove
// PFD(s) for one external application identifier provided by AF
type PfdData struct {
	// Each element uniquely identifies external application identifier
	ExternalAppID string `json:"externalAppID"`
	// Link to the resource. This parameter shall be supplied by the AF in
	// HTTP responses that include an object of PfdData type
	Self Link `json:"self,omitempty"`
	// Contains the PFDs of the external application identifier. Each PFD is
	// identified in the map via a key containing the PFD identifier.
	Pfds map[string]Pfd `json:"pfds"`
	// Indicates that the list of PFDs in this request should be deployed
	// within the time interval indicated by the Allowed Delay
	AllowedDelay *DurationSecRm `json:"allowedDelay,omitempty"`
	// SCEF supplied property, inclusion of this property means the allowed
	// delayed cannot be satisfied, i.e. it is smaller than the caching time,
	// but the PFD data is still stored.
	CachingTime *DurationSecRo `json:"cachingTime,omitempty"`
}

// PfdManagement resource for a PFD management request
type PfdManagement struct {
	// Link to the resource "Individual PFD Management Transaction".
	// This parameter shall be supplied by the AF in HTTP responses.
	Self Link `json:"self,omitempty"`
	// String identifying supported optional features of PFD Management
	// This attribute shall be provided in the POST request and in the
	// response of successful resource creation.
	SuppFeat *SupportedFeatures `json:"suppFeat,omitempty"`
	// Each element uniquely identifies the PFDs for an external application
	// identifier. Each element is identified in the map via an external
	// application identifier as key. The response shall include successfully
	// provisioned PFD data of application(s).
	PfdDatas map[string]PfdData `json:"pfdDatas"`
	// Supplied by the AF and contains the external application identifiers
	// for which PFD(s) are not added or modified successfully. The failure
	// reason is also included. Each element provides the related information
	// for one or more external application identifier(s) and is identified in
	// the map via the failure identifier as key.
	PfdReports map[string]PfdReport `json:"pfdReports,omitempty"`
}

// FailureCode represents the failure reason of the PFD management
type FailureCode string

// Possible values of FailureCode
const (
	// This value indicates that something functions wrongly in PFD
	// provisioning or the PFD provisioning does not function at all.
	Malfunction FailureCode = "MALFUNCTION"
	// This value indicates there is resource limitation for PFD storage.
	ResourceLimitation = "RESOURCE_LIMITATION"
	// This value indicates that the allowed delay is too short and PFD(s) are
	// not stored
	ShortDelay = "SHORT_DELAY"
	// The received external application identifier(s) are already provisioned
	AppIDDuplicated = "APP_ID_DUPLICATED"
	// Other reason specified
	OtherReason = "OTHER_REASON"
)

// PfdReport is the type that represents a PFD report to indicate the
// external application identifier(s) which PFD(s) are not added or
// modified successfully and corresponding failure reason.
type PfdReport struct {
	// Identifies the external application identifier(s) which PFD(s) are not
	// added or modified successfully
	ExternalAppIds []string `json:"externalAppIds"`
	// Identifies the failure reason
	FailureCode FailureCode `json:"failureCode"`
	// It shall be included when the allowed delayed cannot be satisfied, i.e.
	// it is smaller than the caching time configured in fetching PFD.
	CachingTime *DurationSec `json:"cachingTime,omitempty"`
}
